package com.loyal.client.server;

import android.content.Context;
import android.content.DialogInterface;
import android.os.OperationCanceledException;

import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.loyal.client.LoadingHandler;
import com.loyal.client.RetroCallManager;
import com.loyal.client.ClientConfig;
import com.loyal.client.impl.DialogCallback;
import com.loyal.client.impl.SubscriberCallback;
import com.loyal.client.impl.Subscriber;

/**
 * 顶层设计
 */
public abstract class BasicSubscriberImpl<T, R extends RetroCallManager> implements Subscriber<T>,  DialogInterface.OnCancelListener {
    private SubscriberCallback<T> subscribeListener;
    private int mWhat = 2;
    private Object object;
    private boolean showProgressDialog = false;//default=false
    private LoadingHandler handler;
    private DialogCallback dialogCallback;
    private final R manager;
    private Context mContext;
    private int dialogTheme;
    private static final String CANCEL_MESSAGE = "操作已取消";

    protected @NonNull
    abstract R manager();

    public abstract void createServer(R manager);

    public BasicSubscriberImpl() {
        this(ClientConfig.getInstance());
    }

    public BasicSubscriberImpl(@NonNull ClientConfig config) {
        manager = manager();
        manager.build(config);
        createServer(manager);
    }

    @Override
    public Subscriber<T> withContext(@Nullable Context context) {
        return withContext(context, 0);
    }

    @Override
    public Subscriber<T> withContext(@Nullable Context context, int theme) {
        this.mContext = context;
        this.dialogTheme = theme;
        return this;
    }

    private void initDialog() {
        if (null == mContext)
            return;
        if (null == handler) {
            handler = new LoadingHandler(mContext, dialogTheme, this);
            setDialogMessage("loading...")
                    .setCancelable(true)
                    .setCanceledOnTouchOutside(false);
            handler.showDialog();
        }
    }

    public String baseUrl() {
        return manager.baseUrl();
    }

    @Override
    public Subscriber<T> setWhat(@IntRange(from = 2, to = 1000) int what) {
        this.mWhat = what;
        return this;
    }

    @Override
    public Subscriber<T> showProgressDialog(boolean showProgressDialog) {
        this.showProgressDialog = showProgressDialog;
        return this;
    }

    @Override
    public Subscriber<T> setDialogMessage(CharSequence message) {
        if (null != handler)
            handler.setMessage(message);
        return this;
    }

    private void checkDialog() {

    }

    @Override
    public Subscriber<T> setTag(Object objTag) {
        this.object = objTag;
        return this;
    }

    @Override
    public Subscriber<T> setCancelable(boolean cancelable) {
        if (null != handler)
            handler.setCancelable(cancelable);
        return this;
    }

    /**
     * 自定义加载事件
     */
    @Override
    public void setDialogCallback(DialogCallback dialogCallback) {
        this.dialogCallback = dialogCallback;
    }

    @Override
    public void setCanceledOnTouchOutside(boolean flag) {
        if (null != handler)
            handler.setCanceledOnTouchOutside(flag);
    }

    @Override
    public void setSubscribeListener(SubscriberCallback<T> listener) {
        this.subscribeListener = listener;
    }

    /**
     * 若在Retrofit+OkHttp中调用，则此行代码要放置在最后调用
     */
    public void showDialog() {
        if (null != dialogCallback) {
            dialogCallback.onDialogCallback(DialogCallback.SHOW);
            return;
        }
        if (showProgressDialog) {
            initDialog();
        }
    }

    private void dismissDialog() {
        if (null != dialogCallback) {
            dialogCallback.onDialogCallback(DialogCallback.DISMISS);
            return;
        }
        showProgressDialog = false;
        if (null != handler) {
            handler.dismissDialog();
            handler = null;
        }
    }

    /**
     * 回调
     */
    public void onNext(@NonNull T result) {
        if (null != subscribeListener)
            subscribeListener.onResult(mWhat, object, result);
    }

    public void onError(@NonNull Throwable e) {
        dismissDialog();
        boolean cancelError = e instanceof OperationCanceledException;
        if (null != subscribeListener)
            subscribeListener.onError(mWhat, object, e);
        if (cancelError) {
            subscribeListener = null;
        }
        dispose();
    }

    public void onComplete() {
        dismissDialog();
        dispose();
    }

    @Override
    public void onCancel(DialogInterface dialog) {
        onError(new OperationCanceledException(CANCEL_MESSAGE));
        onComplete();
    }

    /*中断/取消任务*/
    @Override
    public void unsubscribe() {
        onComplete();
    }

}
